/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package tetris.model.navigation;

import java.util.HashMap;

/**
 *
 * @author vadim
 */
public class Position {
    
    private int _row = 0;
    private int _column = 0;
    
    private static PositionRange _horizontalRange = new PositionRange(0, 0);

    /**
     * Функция задания горизонтального диапозона позиций.
     * @param min минимальное значение.
     * @param max максимальное значение.
     */
    public static void setHorizontalRange(int min, int max){
        if(PositionRange.isValidRange(min, max))
        { _horizontalRange = new PositionRange(min, max); }
    }

    /**
     * Конструктор.
     * @param row вертикатьная позиция.
     * @param column горизонтальная  позиция
     */
    public Position(int row,int column) {
        if(row>0) {
            _row = row;
        }
        if(column>0) {
            _column = column;
        }
    }

    /**
     * Горизонтальный диапозон позиций.
     * @return
     */
    public static PositionRange horizontalRange(){
      return _horizontalRange;
    }
    private static PositionRange _verticalRange = new PositionRange(0, 0);

    /**
     * Функция задания вертикального диапозона позиций.
     * @param min минимальное значение.
     * @param max максимальное значение.
     */
    public static void setVerticalRange(int min, int max){
        if(PositionRange.isValidRange(min, max))
        { _verticalRange = new PositionRange(min, max); }
    }
    
    /**
     * Вертикальный диапозон позиций.
     * @return
     */
    public static PositionRange verticalRange(){
        return _verticalRange;
    }
    
    /**
     * Функция проверки наличия у позиции соседа в указанном направлении.
     * @param direct направление.
     * @return результат.
     */
    public boolean hasNext(Direction direct){
        
        int[] newPos = calcNewPosition(_row, _column, direct);
        return isValid(newPos[0], newPos[1]);
    }
    
    /**
     * Функция возвращающая соседа позиции в указанном направлении.
     * @param direct направление.
     * @return сосед.
     */
    public Position next(Direction direct) {
        if (this.hasNext(direct)) {
            int[] newPos = calcNewPosition(_row, _column, direct);
            Position pos = new Position(newPos[0], newPos[1]);
            return pos;
            
        }
        return null;
    }
    // Вовзвращает массив из двух элементов: индекс строки, индекс столбца
    private int[] calcNewPosition(int row, int col, Direction direct){
        
        // Таблица смещения для различных направлений: (горизонталь,вертикаль)
        HashMap<Direction, int [] > offset=  new  HashMap<Direction, int [] >();
        
        offset.put(Direction.down(),   new int []{ 0,  -1} );
        offset.put(Direction.right(),    new int []{ 1,  0} );
        offset.put(Direction.left(),    new int []{-1,  0} );
        
        int[] newPos = new int[2];
        
        newPos[0] = _row + offset.get(direct)[1];
        newPos[1] = _column + offset.get(direct)[0];
        
        return newPos;
    }
    
    // Позиция может стать невалидной, если изменились диапазоны допустимых значений

    /**
     * Функция проверки валидности позиции.
     * @return результат.
     */
        public boolean isValid(){
        return isValid(_row, _column);
    }
    
    /**
     * Функция проверки валидности позиции.
     * @param row вертикальная координата.
     * @param col горизонтальная координата.
     * @return результат.
     */
    public static boolean isValid(int row, int col){
        return _horizontalRange.contains(col) && _verticalRange.contains(row);
   }
    
    /**
     * Вертикальная координата.
     * @return
     */
    public int row() {
        return _row;
    }
    
    /**
     * Горизонтальная координата.
     * @return
     */
    public int column() {
        return _column;
    }
}
